﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;

namespace KnBinarySerializer.Field
{
    public interface IClassField
    {
        bool CanWrite { get; }
        object GetValue(object obj, object[] index);
        void SetValue(object obj, object value, object[] index);

        Type PropertyType { get; }

        string Name {  get; }
    }
    public class ClassProperty : IClassField
    {
        private Func<object, object> _getter;
        private Action<object, object> _setter;
        public string Name { get; set; }
        private PropertyInfo propertyInfo;
        public ClassProperty(PropertyInfo pProperty)
        {
            this.propertyInfo = pProperty;
            _getter = MethodHelper.CreateGet<object>(propertyInfo);
            _setter = MethodHelper.CreateSet<object>(propertyInfo);
        }
        public bool CanWrite { get { return this.propertyInfo.CanWrite; } }

        public Type PropertyType
        {
            get { return this.propertyInfo.PropertyType; }
        }

        public object GetValue(object obj, object[] index)
        {
            //return this.propertyInfo.GetValue(obj, index);
            return _getter(obj);
        }

        public void SetValue(object obj, object value, object[] index)
        {
            //this.propertyInfo.SetValue(obj, value, index);
            _setter(obj,value);
        }
    }

    public class ClassField : IClassField
    {
        private Func<object, object> _getter;
        private Action<object, object> _setter;
        public string Name { get; set; }

        private FieldInfo fieldInfo;
        public ClassField(FieldInfo pFieldInfo)
        {
            this.fieldInfo = pFieldInfo;
            _getter = MethodHelper.CreateGet<object>(pFieldInfo);
            _setter = MethodHelper.CreateSet<object>(pFieldInfo);
        }
        public bool CanWrite { get { return true; } }

        public Type PropertyType { get { return this.fieldInfo.FieldType; } }

        public object GetValue(object obj, object[] index)
        {
            //return this.fieldInfo.GetValue(obj);
            return _getter(obj);
        }

        public void SetValue(object obj, object value, object[] index)
        {
            //this.fieldInfo.SetValue(obj, value);
            _setter(obj, value);
        }
    }
}
